/**
 *****************************************************************************************************
 * @copyright	(c)  Shenzhen Saiyuan Microelectronics Co., Ltd
 * @file	         main.c
 * @author
 * @version
 * @date
 * @brief
 * @details         Contains the MCU initialization function and its H file
 *****************************************************************************************************
 * @attention
 *
 *****************************************************************************************************
 */
/*******************Includes************************************************************************/

#include "SC_Init.h"
#include "SC_it.h"
#include "..\Drivers\SCDriver_list.h"
#include "HeadFiles\SysFunVarDefine.h"
#include "Alarm_Clock/Alarm_Clock.h"
#include "Beep/Beep.h"
#include "Menu\Menu.h"
#include "Font\Font .h"
/**************************************Generated by EasyCodeCube*************************************/
// Forbid editing areas between the labels !!!

/*************************************.Generated by EasyCodeCube.************************************/

/**
 * @brief This function implements main function.
 * @note
 * @param
 */

int a = 0;
int gate = 0, jaw = 0, lift = 0;
int stablization = 0;
unsigned char Init_Finish = 0;
extern int count;
unsigned char Time_Display[6] = {0}, Date_Display[7] = {0};
CLOCK CurrentClock;
unsigned char UART1_FLAG = 0;
unsigned char TxData[11];
unsigned char RxData[11];
unsigned char Buds[Buds_Num] = {0};
int rgb_;
unsigned char l_min = 0;
#define DISP_H 64  // 屏幕高度
#define DISP_W 128 // 屏幕宽度
uint8_t *buf_ptr;  // 指向屏幕缓冲的指�?
uint16_t buf_len;  // 缓冲长度
u8g2_t u8g2;
int arr = 0;
float cc = 0, cc1 = 0;
uint16_t Freq;
int pu;
extern int TR, TG, TB;
int main(void)
{
    IcResourceInit();
    // u8g2Init(&u8g2);
    OLED_Init();
    // GPIO_WriteBit(GPIOA, GPIO_Pin_15, Bit_RESET);
    // GPIO_WriteBit(GPIOC, GPIO_Pin_10, Bit_SET);
    OLED_Draw_Picture(0, 0, 128, 8, P_Logo);
    OLED_refresh_gram();
    Delay_ms(200);
    OLED_refresh_gram();
    CurrentClock.Day = 1;
    CurrentClock.Hour = 0;
    CurrentClock.Min = 0;
    CurrentClock.Month = 1;
    CurrentClock.Sec = 0;
    CurrentClock.Week = 1;
    CurrentClock.Year = 24;
    Init_Finish = 1;
    OLED_operate_gram(PEN_CLEAR);
    OLED_refresh_gram();
    TIM_PWMSetDuty(TIM2, TIM_PWMChannel_PWMA, Volume);
    l_min = CurrentClock.Min;

    while (1)
    {
        // PWM_SetDuty(PWM0, PWM_Channel_1, 9999); // red
        // PWM_SetDuty(PWM0, PWM_Channel_2, 0);    // green
        // PWM_SetDuty(PWM0, PWM_Channel_3, 0);    // blue
        // u8g2_DrawFrame(&u8g2, 10, 10, 64, 128);
        // u8g2_SendBuffer(&u8g2);
        OLED_operate_gram(PEN_CLEAR);
        if (CurrentClock.Min != l_min) // 以分钟为周期
        {
            for (int i = 0; i < NUM_OF_ALARM; i++)
                Alarm_Check(Alarm_Clock + i, &CurrentClock);
            l_min = CurrentClock.Min;
        }
        if (UART1_FLAG) // 如果UART1接收完所有数�?
        {
            UART1_FLAG = 0;
            DMA_SoftwareTrigger(DMA1);
            {
                uint32_t delay_time = 400000;
                while (delay_time--)
                    ;
            }
            if (DMA_GetFlagStatus(DMA1, DMA_FLAG_TCIF)) // 如果DMA1发送完�?
            {
                DMA_ClearFlag(DMA1, DMA_FLAG_TCIF);
                DMA_SetCurrDataCounter(DMA1, 11);
                UART_DMACmd(UART1, UART_DMAReq_TX, DISABLE);
                UART_DMACmd(UART1, UART_DMAReq_TX, ENABLE);
            }
        }

        // 时间更新
        if (RxData[0] == 77 && RxData[1] == 0 && RxData[10] == 88) // 校准
        {
            CurrentClock.Year = RxData[2];
            CurrentClock.Month = RxData[3];
            CurrentClock.Day = RxData[4];
            CurrentClock.Week = RxData[5];
            CurrentClock.Hour = RxData[6];
            CurrentClock.Min = RxData[7];
            CurrentClock.Sec = RxData[8];
            RxData[0] = 70;
        }
        //==============闹钟设置
        else if (RxData[Front_Check] == 77 && RxData[Clock] == 1 && RxData[End_Check] == 88) // 校准
        {
            if ((RxData[Func] == 0 || RxData[Func] == 0) && RxData[id] <= NUM_OF_ALARM)
            {
                Alarm_Modi_Setting(Alarm_Clock + RxData[id] - 1, On);
                Alarm_Modi_Month(Alarm_Clock + RxData[id] - 1, RxData[month]);
                Alarm_Modi_day(Alarm_Clock + RxData[id] - 1, RxData[day]);
                Alarm_Modi_Hour(Alarm_Clock + RxData[id] - 1, RxData[hour]);
                Alarm_Modi_Min(Alarm_Clock + RxData[id] - 1, RxData[minute]);
                Alarm_Reset(Alarm_Clock + RxData[id] - 1);
            }
            else if (RxData[Func] == 1 || RxData[Func] == 3)
            {
                Alarm_Modi_Setting(Alarm_Clock + RxData[id] - 1, Off);
            }
            RxData[Front_Check] = 70;
            pu++;
        }
        //=============================================================菜单======================================
        // OLED_printf(0, 18, "%d", OLED_Page);
        if (OLED_Page == Time_Page)
        {
            Time_Display[0] = CurrentClock.Sec % 10;
            Time_Display[1] = CurrentClock.Sec / 10;
            Time_Display[2] = CurrentClock.Min % 10;
            Time_Display[3] = CurrentClock.Min / 10;
            Time_Display[4] = CurrentClock.Hour % 10;
            Time_Display[5] = CurrentClock.Hour / 10;
            Date_Display[0] = CurrentClock.Day % 10;
            Date_Display[1] = CurrentClock.Day / 10;
            Date_Display[2] = CurrentClock.Month % 10;
            Date_Display[3] = CurrentClock.Month / 10;
            Date_Display[4] = (CurrentClock.Year) % 10;
            Date_Display[5] = ((CurrentClock.Year) % 100) / 10;
            Date_Display[6] = (CurrentClock.Year) / 100;
            OLED_printf(4, 0, "%d--%d--%d", TR, TG, TB);
            // OLED_printf(4, 2, "%d", Alarm_Clock[0].Status);
            OLED_printf(0, 1, "/__/*SOC_CLOCK* \\__\\");
            OLED_printf(1, 1, "\\  \\            /  /");
            OLED_Shift_Down(30, 1, 100, 24);
            OLED_Reverse(1, 1, 126, 24);
            OLED_printf(2, 7, "%d%d:%d%d:%d%d", Time_Display[5], Time_Display[4], Time_Display[3], Time_Display[2], Time_Display[1], Time_Display[0]);
            // OLED_printf(3, 0, "op:%d-mo:%d-pa:%d", mode, option, OLED_Page);
            // OLED_printf(3, 0, "%d%d%d%d%d%d%d%d%d%d", RxData[0], RxData[1], RxData[2], RxData[3], RxData[4], RxData[3], RxData[6], RxData[7], RxData[8], RxData[9]);
            OLED_printf(3, 6, "2%d%d%d/%d%d/%d%d", Date_Display[6], Date_Display[5], Date_Display[4], Date_Display[3], Date_Display[2], Date_Display[1], Date_Display[0]);
            // OLED_printf(4, 4, "Fuck the world!!!");
        }
        else if (OLED_Page == Menu_Page)
        {
            // OLED_printf(0, 0, "%d", mode);
            // OLED_printf(0, 10, "V");
            if (mode < 0)
                mode += Num_Of_Menu;
            if (mode > Num_Of_Menu - 1)
                mode -= Num_Of_Menu;
            for (int i = 0; i < Num_Of_Menu; i++)
            {
                Menu_X[i] = (uint8_t)MAIN_MENU_Limit(-mode + 1 + i) * 8;
                if ((mode <= i - Num_Of_Menu + 1 && mode >= i - Num_Of_Menu - 1) ||
                    (mode <= i + 1 && mode >= i - 1) ||
                    (mode <= i + Num_Of_Menu + 1 && mode >= i + Num_Of_Menu - 1))
                {
                    OLED_printf(4, Menu_X[i], Menu_Char[i]);
                    OLED_Draw_Picture(Menu_X[i] * 6, 2, Menu_X[i] * 6 + 32, 6, Menu_Picture[i]);
                }
            }
            OLED_Shift_Up(45, 10, 80, 60);
            OLED_Reverse(45, 5, 83, 54);
        }
        else if (OLED_Page == Sub_Page)
        {
            switch (mode)
            {
            case MENU_Time:
                Return_Time_Page();
                break;
            case MENU_Light:
                if (Light_Choose > 4)
                    Light_Choose = 4;
                if (Light_Choose < 1)
                    Light_Choose = 1;
                OLED_printf(Light_Choose, 3, ">");
                OLED_printf(Light_Choose, 17, "<");
                OLED_printf(0, 1, "\\/**Choose_Color**\\/");
                OLED_printf(1, 9, "RED");    // o=2
                OLED_printf(2, 8, "GREEN");  // o=1
                OLED_printf(3, 9, "BLUE");   // o=0
                OLED_printf(4, 8, "RANDOM"); // o=0
                break;
            case MENU_Music:
                if (Song_Choose > 3)
                    Song_Choose = 3;
                if (Song_Choose < 1)
                    Song_Choose = 1;
                OLED_printf(Song_Choose, 3, ">");
                OLED_printf(Song_Choose, 17, "<");
                OLED_printf(1, 8, "QRGJC");     // o=2
                OLED_printf(2, 6, "SCUT_SONG"); // o=1
                OLED_printf(3, 7, "Molihua");   // o=0
                if (TMP_Play_Song == 0)
                {
                    Music_Start((Typedef_Song)(Song_Choose - 1));
                    TMP_Play_Song = 1;
                }
                break;
            case MENU_Alarm_Clock:
                if (TMP_ACLOCK <= 0)
                    TMP_ACLOCK += 8;
                else if (TMP_ACLOCK > NUM_OF_ALARM)
                    TMP_ACLOCK -= 8;
                OLED_printf(2, 0, ">");
                // OLED_printf(0, 0, "%d", TMP_ACLOCK);
                for (int i = 0; i < NUM_OF_ALARM; i++)
                {
                    if (Alarm_Clock[i].Setting == On)
                        OLED_printf((uint8_t)Alarm_Print_Limit(-TMP_ACLOCK + i + 3), 2,
                                    "%d-%d%d/%d%d %d%d:%d%d  -ON-", i + 1,
                                    Alarm_Clock[i].Time.Month / 10, Alarm_Clock[i].Time.Month % 10,
                                    Alarm_Clock[i].Time.Day / 10, Alarm_Clock[i].Time.Day % 10,
                                    Alarm_Clock[i].Time.Hour / 10, Alarm_Clock[i].Time.Hour % 10,
                                    Alarm_Clock[i].Time.Min / 10, Alarm_Clock[i].Time.Min % 10);
                    else
                        OLED_printf((uint8_t)Alarm_Print_Limit(-TMP_ACLOCK + i + 3), 2,
                                    "%d-%d%d/%d%d %d%d:%d%d -OFF-", i + 1,
                                    Alarm_Clock[i].Time.Month / 10, Alarm_Clock[i].Time.Month % 10,
                                    Alarm_Clock[i].Time.Day / 10, Alarm_Clock[i].Time.Day % 10,
                                    Alarm_Clock[i].Time.Hour / 10, Alarm_Clock[i].Time.Hour % 10,
                                    Alarm_Clock[i].Time.Min / 10, Alarm_Clock[i].Time.Min % 10);
                }
                //                OLED_Shift_Left(10, 25, 125, 35);
                OLED_Reverse(4, 25, 125, 35);
                OLED_draw_point(4, 29, PEN_CLEAR);
                OLED_draw_point(2, 25, PEN_WRITE);
                OLED_draw_point(3, 25, PEN_WRITE);
                OLED_draw_point(3, 26, PEN_WRITE);
                OLED_draw_point(2, 33, PEN_WRITE);
                OLED_draw_point(3, 32, PEN_WRITE);
                OLED_draw_point(3, 33, PEN_WRITE);
                OLED_draw_point(1, 34, PEN_WRITE);
                OLED_draw_point(2, 34, PEN_WRITE);
                OLED_draw_point(3, 34, PEN_WRITE);
                OLED_draw_point(1, 33, PEN_CLEAR);
                OLED_draw_point(2, 32, PEN_CLEAR);
                OLED_draw_point(3, 31, PEN_CLEAR);
                OLED_draw_point(4, 30, PEN_CLEAR);
                OLED_draw_point(5, 29, PEN_CLEAR);
                break;
            case MENU_Setting:
                Return_Time_Page();
                break;
            case MENU_About:
                OLED_printf(0, 7, ">About<");
                OLED_printf(1, 2, ">Smart Alarm Clock<");
                OLED_printf(2, 2, "Development Team: ");
                OLED_printf(3, 4, "Saiyuanbeidui ");
                OLED_printf(4, 1, "COLIN  JASPER   LAW");
                break;
            default:
                Return_Time_Page();
                break;
            }
        }
        else if (OLED_Page == Detail_Page)
        {
            switch (mode)
            {
            case MENU_Music:
                Music_Exit();
                Return_Time_Page();
                break;
            case MENU_Alarm_Clock:
                TMP_MODI_ACLOCK = limited(TMP_MODI_ACLOCK, 0, (int)NUM_OF_MODIFY - 1);
                if (Modi_Alarm_First_time)
                {
                    Alarm_Copy(&MENU_TMP_ALARM, Alarm_Clock + TMP_ACLOCK - 1);
                    Modi_Alarm_First_time = 0;
                }
                // OLED_printf(1, (uint8_t)(2 + MODI_ALARM[TMP_MODI_ACLOCK]), "V");
                // OLED_printf(3, (uint8_t)(2 + MODI_ALARM[TMP_MODI_ACLOCK]), "^");
                if (MENU_TMP_ALARM.Time.Month == 1 || MENU_TMP_ALARM.Time.Month == 3 || MENU_TMP_ALARM.Time.Month == 5 || MENU_TMP_ALARM.Time.Month == 7 || MENU_TMP_ALARM.Time.Month == 8 || MENU_TMP_ALARM.Time.Month == 10 || MENU_TMP_ALARM.Time.Month == 12)
                    MENU_TMP_ALARM.Time.Day = limited(MENU_TMP_ALARM.Time.Day, 1, 31);
                else if (MENU_TMP_ALARM.Time.Month == 2)
                    MENU_TMP_ALARM.Time.Day = limited(MENU_TMP_ALARM.Time.Day, 1, 29);
                else
                    MENU_TMP_ALARM.Time.Day = limited(MENU_TMP_ALARM.Time.Day, 1, 30);
                MENU_TMP_ALARM.Time.Month = limited(MENU_TMP_ALARM.Time.Month, 1, 12);
                MENU_TMP_ALARM.Time.Min = limited(MENU_TMP_ALARM.Time.Min, 0, 59);
                MENU_TMP_ALARM.Time.Hour = limited(MENU_TMP_ALARM.Time.Hour, 0, 23);
                if (MENU_TMP_ALARM.Setting == On)
                    OLED_printf(2, 2,
                                "%d-%d%d/%d%d %d%d:%d%d  -ON-", TMP_ACLOCK,
                                MENU_TMP_ALARM.Time.Month / 10, MENU_TMP_ALARM.Time.Month % 10,
                                MENU_TMP_ALARM.Time.Day / 10, MENU_TMP_ALARM.Time.Day % 10,
                                MENU_TMP_ALARM.Time.Hour / 10, MENU_TMP_ALARM.Time.Hour % 10,
                                MENU_TMP_ALARM.Time.Min / 10, MENU_TMP_ALARM.Time.Min % 10);
                else
                    OLED_printf(2, 2,
                                "%d-%d%d/%d%d %d%d:%d%d -OFF-", TMP_ACLOCK,
                                MENU_TMP_ALARM.Time.Month / 10, MENU_TMP_ALARM.Time.Month % 10,
                                MENU_TMP_ALARM.Time.Day / 10, MENU_TMP_ALARM.Time.Day % 10,
                                MENU_TMP_ALARM.Time.Hour / 10, MENU_TMP_ALARM.Time.Hour % 10,
                                MENU_TMP_ALARM.Time.Min / 10, MENU_TMP_ALARM.Time.Min % 10);
                Modi_Dispaly_base = 12 + MODI_ALARM[TMP_MODI_ACLOCK] * 6;
                OLED_Reverse(Modi_Dispaly_base, 25, Modi_Dispaly_base + 5, 35);
                // OLED_Reverse(11+MODI_ALARM[TMP_MODI_ACLOCK], 25, 18, 35);
                switch (TMP_MODI_ACLOCK)
                {
                case MODI_Month:
                    OLED_printf(4, 8, "Month");
                    break;
                case MODI_Day:
                    OLED_printf(4, 8, "Day");
                    break;
                case MODI_Hour:
                    OLED_printf(4, 8, "Hour");
                    break;
                case MODI_Min_1:
                    OLED_printf(4, 9, "Min");
                    break;
                case MODI_Min_2:
                    OLED_printf(4, 9, "Min");
                    break;
                case MODI_Setting:
                    OLED_printf(4, 7, "SETTING");
                    break;
                default:
                    OLED_printf(4, 8, "MODI");
                    break;
                }
                break;
            default:
                Return_Time_Page();
                break;
            }
        }
        else if (OLED_Page == Final_Page)
        {
            switch (mode)
            {
            case MENU_Alarm_Clock:
                if (MENU_TMP_ALARM.Time.Month == 1 || MENU_TMP_ALARM.Time.Month == 3 || MENU_TMP_ALARM.Time.Month == 5 || MENU_TMP_ALARM.Time.Month == 7 || MENU_TMP_ALARM.Time.Month == 8 || MENU_TMP_ALARM.Time.Month == 10 || MENU_TMP_ALARM.Time.Month == 12)
                    MENU_TMP_ALARM.Time.Day = limited(MENU_TMP_ALARM.Time.Day, 1, 31);
                else if (MENU_TMP_ALARM.Time.Month == 2)
                    MENU_TMP_ALARM.Time.Day = limited(MENU_TMP_ALARM.Time.Day, 1, 29);
                else
                    MENU_TMP_ALARM.Time.Day = limited(MENU_TMP_ALARM.Time.Day, 1, 30);
                MENU_TMP_ALARM.Time.Month = limited(MENU_TMP_ALARM.Time.Month, 1, 12);
                MENU_TMP_ALARM.Time.Min = limited(MENU_TMP_ALARM.Time.Min, 0, 59);
                MENU_TMP_ALARM.Time.Hour = limited(MENU_TMP_ALARM.Time.Hour, 0, 23);
                Alarm_Copy(Alarm_Clock + TMP_ACLOCK - 1, &MENU_TMP_ALARM);
                if (Alarm_Clock[TMP_ACLOCK - 1].Setting == On)
                    OLED_printf(2, 2,
                                "%d-%d%d/%d%d %d%d:%d%d  -ON-", TMP_ACLOCK,
                                Alarm_Clock[TMP_ACLOCK - 1].Time.Month / 10, Alarm_Clock[TMP_ACLOCK - 1].Time.Month % 10,
                                Alarm_Clock[TMP_ACLOCK - 1].Time.Day / 10, Alarm_Clock[TMP_ACLOCK - 1].Time.Day % 10,
                                Alarm_Clock[TMP_ACLOCK - 1].Time.Hour / 10, Alarm_Clock[TMP_ACLOCK - 1].Time.Hour % 10,
                                Alarm_Clock[TMP_ACLOCK - 1].Time.Min / 10, Alarm_Clock[TMP_ACLOCK - 1].Time.Min % 10);
                else
                    OLED_printf(2, 2,
                                "%d-%d%d/%d%d %d%d:%d%d -OFF-", TMP_ACLOCK,
                                Alarm_Clock[TMP_ACLOCK - 1].Time.Month / 10, Alarm_Clock[TMP_ACLOCK - 1].Time.Month % 10,
                                Alarm_Clock[TMP_ACLOCK - 1].Time.Day / 10, Alarm_Clock[TMP_ACLOCK - 1].Time.Day % 10,
                                Alarm_Clock[TMP_ACLOCK - 1].Time.Hour / 10, Alarm_Clock[TMP_ACLOCK - 1].Time.Hour % 10,
                                Alarm_Clock[TMP_ACLOCK - 1].Time.Min / 10, Alarm_Clock[TMP_ACLOCK - 1].Time.Min % 10);
                Modi_Alarm_First_time = 1;
                Return_Time_Page();
                break;

            default:
                Return_Time_Page();
                break;
            }
        }
        else
            Return_Time_Page();
        // OLED_printf(0, 20, "%d", stablization);
        OLED_refresh_gram();
    }
}
/*
 if (mode == 2)
            { //---------------------moving
                if (option > 2)
                {
                    option = 2;
                }
                if (option < 0)
                {
                    option = 0;
                }
                option0 = option;
                OLED_show_string(option0, 14, (uint8_t *)"1"); // o=2
                option1 = option + 1;
                OLED_show_string(option1, 14, (uint8_t *)"2"); // o=1
                option2 = option + 2;
                OLED_show_string(option2, 14, (uint8_t *)"3"); // o=0
            }
            else if (mode == 1)
            {
                if (option > 2)
                    option = 2;
                if (option < 0)
                    option = 0;
                option0 = option;
                OLED_show_string(option0, 14, (uint8_t *)"RGH"); // o=2
                option1 = option + 1;
                OLED_show_string(option1, 14, (uint8_t *)"MID"); // o=1
                option2 = option + 2;
                OLED_show_string(option2, 14, (uint8_t *)"TIY"); // o=0
            }
            else if (mode == 0)
            {
                if (option <= 2)
                    option += 10;
                if (option >= 11)
                    option -= 10;
                option1 = option;
                if (option1 > 4)
                    option1 -= 10;
                OLED_show_string(option1, 14, (uint8_t *)"prot"); // 2
                option2 = option + 1;
                if (option2 > 4)
                    option2 -= 10;
                OLED_show_string(option2, 14, (uint8_t *)"up"); // 1
                option3 = option + 2;
                if (option3 > 4)
                    option3 -= 10;
                OLED_show_string(option3, 14, (uint8_t *)"plac"); // 10
                option4 = option + 3;
                if (option4 > 4)
                    option4 -= 10;
                OLED_show_string(option4, 14, (uint8_t *)"down"); // 9
                option5 = option + 4;
                if (option5 > 4)
                    option5 -= 10;
                OLED_show_string(option5, 14, (uint8_t *)"plac"); // 8
                option6 = option + 5;
                if (option6 > 4)
                    option6 -= 10;
                OLED_show_string(option6, 14, (uint8_t *)"free"); // 7
                option7 = option + 6;
                if (option7 > 4)
                    option7 -= 10;
                OLED_show_string(option7, 14, (uint8_t *)"mid"); // 6
                option8 = option + 7;
                if (option8 > 4)
                    option8 -= 10;
                OLED_show_string(option8, 14, (uint8_t *)"plac"); // 5
                option9 = option + 8;
                if (option9 > 4)
                    option9 -= 10;
                OLED_show_string(option9, 14, (uint8_t *)"tou"); // 4
                option10 = option + 9;
                if (option10 > 4)
                    option10 -= 10;
                OLED_show_string(option10, 14, (uint8_t *)"plac"); // 3
            }
*/
